home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1 / Nebula One.iso / Graphics / Misc / aa_m68k_Only / NDCamera.0.21 / Source / MiscSources.subproj / MiscStringComparing.m < prev    next >
Encoding:
Text File  |  1995-04-12  |  8.2 KB  |  297 lines

  1. //
  2. //    MiscStringComparing.m
  3. //        Written by Don Yacktman Copyright (c) 1993 by Don Yacktman.
  4. //                Version 1.95  All rights reserved.
  5. //        This notice may not be removed from this source code.
  6. //
  7. //    This object is included in the MiscKit by permission from the author
  8. //    and its use is governed by the MiscKit license, found in the file
  9. //    "LICENSE.rtf" in the MiscKit distribution.  Please refer to that file
  10. //    for a list of all applicable permissions and restrictions.
  11. //    
  12.  
  13. #import <misckit/MiscString.h>
  14.  
  15. @implementation MiscString(Comparing)
  16.  
  17. // This category is composed of methods which compare
  18. // MiscStrings with other strings.
  19.  
  20. - (BOOL)isEqual:anObject
  21. {
  22.     if (anObject == self) return YES;
  23.     // doesn't have to be a MiscString object to be equal...
  24.     if ([anObject respondsTo:@selector(stringValue)]) {
  25.         if (!NXOrderStrings((unsigned char *)buffer,
  26.                 (unsigned char *)[anObject stringValue],
  27.                 YES, -1, orderTable)) return YES;
  28.     }
  29.     return NO;
  30. }
  31.  
  32. - (unsigned int)hash
  33. // Use the NextStep string hashing functiuon NXStrHash()  instead of 
  34. // the pointer hashing function. 
  35. {
  36.     return NXStrHash(NULL, buffer);
  37. }
  38.  
  39. - (int)compareTo:sender
  40. {
  41.     return [self compareTo:sender n:(-1) caseSensitive:YES];
  42. }
  43.  
  44. - (int)compareTo:sender n:(int)n
  45. {
  46.     return [self compareTo:sender n:n caseSensitive:YES];
  47. }
  48.  
  49. - (int)cmp:(const char *)aString
  50. {
  51.     if (!aString && !buffer) return 0;        // both NULL, so "equal"
  52.     if (!aString) return 1;    // only one is NULL, so not equal
  53.     if (!buffer) return -1;    // only one is NULL, so not equal
  54.     return strcmp(buffer, aString);
  55. }
  56.  
  57. - (int)cmp:(const char *)aString n:(int)n
  58. {
  59.     if (!aString && !buffer) return 0;        // both NULL, so "equal"
  60.     if (!aString) return 1;    // only one is NULL, so not equal
  61.     if (!buffer) return -1;    // only one is NULL, so not equal
  62.     // we don't check n; use strncmp's behavior here.
  63.     return strncmp(buffer, aString, n);
  64. }
  65.  
  66. - (int)compareTo:sender caseSensitive:(BOOL)sense
  67. {
  68.     return [self compareTo:sender n:(-1) caseSensitive:sense];
  69. }
  70.  
  71. - (int)compareTo:sender n:(int)n caseSensitive:(BOOL)sense
  72. {
  73.     const char *s; int ret, senderLength, size = n;
  74.     if (!sender) {
  75.         if (!buffer) return 0;
  76.         return 1;
  77.     }
  78.     if (![sender respondsTo:@selector(stringValue)]) return 1; // !=
  79.     s = [sender stringValue];
  80.     if (!buffer && !s) return 0;        // both are NULL
  81.     if (!buffer) return -1;    // buffer is NULL
  82.     if (!s) return 1;    // sender is NULL
  83.     if ([sender respondsTo:@selector(length)]) senderLength = [sender length];
  84.     else senderLength = strlen(s);
  85.     if ((size > length) || (size > senderLength))  {
  86.         size = MIN(length, senderLength);
  87.         if (!size) if (senderLength) return -1;
  88.         else if (length) return 1;
  89.         else return 0;
  90.     }
  91.     ret = NXOrderStrings((unsigned char *)buffer,
  92.             (unsigned char *)s, sense, size, orderTable);
  93.     if (((size > length) || (size > senderLength)) && (!ret)) {
  94.         if (length < senderLength) return -1;
  95.         if (length > senderLength) return 1;
  96.     }
  97.     return ret;
  98. }
  99.  
  100. - (int)casecmp:(const char *)aString
  101. {
  102.     if (!aString && !buffer) return 0;        // both NULL, so "equal"
  103.     if (!aString || !buffer) return -1;    // only one is NULL, so not equal
  104.     return strcasecmp(buffer, aString);
  105. }
  106.  
  107. - (int)casecmp:(const char *)aString n:(int)n
  108. {
  109.     if (!aString && !buffer) return 0;        // both NULL, so "equal"
  110.     if (!aString || !buffer) return -1;    // only one is NULL, so not equal
  111.     // we don't check n; use strncasecmp's behavior here.
  112.     return strncasecmp(buffer, aString, n);
  113. }
  114.  
  115. - (int)endcmp:(const char *)aString
  116. {
  117.   return [self endcmp:aString n:-1];
  118. }
  119.  
  120. - (int)endcmp:(const char *)aString n:(int)n
  121. {
  122.   id tempStr;
  123.   int retval;
  124.   if (!aString) return -1;
  125.   tempStr = [[self class] newWithString:aString];
  126.   retval = [self endCompareTo:tempStr n:n caseSensitive:YES];
  127.   [tempStr free];
  128.   return retval;
  129. }
  130.  
  131. - (int)endcasecmp:(const char *)aString
  132. {
  133.   return [self endcasecmp:aString n:-1];
  134. }
  135.  
  136. - (int)endcasecmp:(const char *)aString n:(int)n
  137. {
  138.   id tempStr;
  139.   int retval;
  140.   if (!aString) return -1;
  141.   tempStr = [[self class] newWithString:aString];
  142.   retval = [self endCompareTo:tempStr n:n caseSensitive:NO];
  143.   [tempStr free];
  144.   return retval;
  145. }
  146.  
  147. - (int)endCompareTo:(id)sender
  148. {
  149.   return [self endCompareTo:sender n:-1 caseSensitive:YES];
  150. }
  151.  
  152. - (int)endCompareTo:(id)sender caseSensitive:(BOOL)sense
  153. {
  154.   return [self endCompareTo:sender n:-1 caseSensitive:sense];
  155. }
  156.  
  157. - (int)endCompareTo:(id)sender n:(int)n
  158. {
  159.   return [self endCompareTo:sender n:n caseSensitive:YES];
  160. }
  161.  
  162. - (int)endCompareTo:(id)sender n:(int)n caseSensitive:(BOOL)sense
  163. { // DAY: fixed it: sender doesn't have to be a MiscString anymore.
  164.     id tempStr, temp2, temp3;
  165.     int retval, smallLen, senderLength;
  166.     const char *s;
  167.     // unlike MOKit, we allow NULL/empty strings, and we adjust n if
  168.     // it is too big.  also, this method is slower than MOKit complement.
  169.     if (!sender) {
  170.         if (!buffer) return 0;
  171.         return 1;
  172.     }
  173.     if (!([sender respondsTo:@selector(stringValue)])) return -1;
  174.     s = [sender stringValue];
  175.     if (!s || !buffer) return -1;
  176.     if ([sender respondsTo:@selector(length)]) senderLength = [sender length];
  177.     else senderLength = strlen(s);
  178.     // find the shorter of the two lengths
  179.     smallLen = ((length >= senderLength) ? senderLength : length);
  180.     if ((n == -1) || (n > smallLen)) n = smallLen;
  181.     tempStr = [self right:n];
  182.     if ([sender respondsTo:@selector(right:)]) temp2 = [sender right:n];
  183.     else {
  184.         temp3 = [[self class] newWithString:[sender stringValue]];
  185.         temp2 = [temp3 right:n];
  186.         [temp3 free];
  187.     }
  188.     retval = [tempStr compareTo:temp2 caseSensitive:sense];
  189.     [tempStr free];
  190.     [temp2 free];
  191.     return retval;
  192. }
  193.  
  194. //--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--
  195. // Additions for the MiscCompare, MiscEndCompare protocols:
  196. //--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--
  197.  
  198. // We should eventually decide upon a single protocol rather than having
  199. // both the above and these methods.  This is an API bug in a big way.
  200.  
  201. - (int)compare:anObject length:(unsigned long)len ignoreCase:(BOOL)flag
  202. {
  203.     return [self compareTo:anObject n:len
  204.             caseSensitive:(flag ? NO : YES)];
  205. }
  206.  
  207. - (int)compareLiteral:(const char *)literal length:(unsigned long)len ignoreCase:(BOOL)flag
  208. {
  209.     MiscString *aString = [[self class] newWithString:literal];
  210.     int ret = [self compareTo:aString n:len
  211.             caseSensitive:(flag ? NO : YES)];
  212.     [aString free];
  213.     return ret;
  214. }
  215.  
  216. - (int)endCompare:anObject length:(unsigned long)len ignoreCase:(BOOL)flag
  217. {
  218.     return [self endCompareTo:anObject n:len
  219.             caseSensitive:(flag ? NO : YES)];
  220. }
  221.  
  222. - (int)endCompareLiteral:(const char *)literal length:(unsigned long)len ignoreCase:(BOOL)flag
  223. {
  224.     MiscString *aString = [[self class] newWithString:literal];
  225.     int ret = [self endCompareTo:aString n:len
  226.             caseSensitive:(flag ? NO : YES)];
  227.     [aString free];
  228.     return ret;
  229. }
  230.  
  231. //--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--
  232. // convenience methods of protocol that call the above four methods:
  233. //--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--
  234.  
  235. - (int)compare:anObject
  236. {
  237.     return [self compare:anObject length:[self length] ignoreCase:NO];
  238. }
  239.  
  240. - (int)compare:anObject ignoreCase:(BOOL)flag
  241. {
  242.     return [self compare:anObject length:[self length] ignoreCase:flag];
  243. }
  244.  
  245. - (int)compare:anObject length:(unsigned long)len
  246. {
  247.     return [self compare:anObject length:len ignoreCase:NO];
  248. }
  249.  
  250. - (int)compareLiteral:(const char *)literal
  251. {
  252.     return [self compareLiteral:literal length:[self length] ignoreCase:NO];
  253. }
  254.  
  255. - (int)compareLiteral:(const char *)literal ignoreCase:(BOOL)flag
  256. {
  257.     return [self compareLiteral:literal length:[self length] ignoreCase:flag];
  258. }
  259.  
  260. - (int)compareLiteral:(const char *)literal length:(unsigned long)len
  261. {
  262.     return [self compareLiteral:literal length:len ignoreCase:NO];
  263. }
  264.  
  265. - (int)endCompare:anObject
  266. {
  267.     return [self endCompare:anObject length:[self length] ignoreCase:NO];
  268. }
  269.  
  270. - (int)endCompare:anObject ignoreCase:(BOOL)flag
  271. {
  272.     return [self endCompare:anObject length:[self length] ignoreCase:flag];
  273. }
  274.  
  275. - (int)endCompare:anObject length:(unsigned long)len
  276. {
  277.     return [self endCompare:anObject length:len ignoreCase:NO];
  278. }
  279.  
  280. - (int)endCompareLiteral:(const char *)literal
  281. {
  282.     return [self endCompareLiteral:literal length:[self length] ignoreCase:NO];
  283. }
  284.  
  285. - (int)endCompareLiteral:(const char *)literal ignoreCase:(BOOL)flag
  286. {
  287.     return [self endCompareLiteral:literal length:[self length]
  288.             ignoreCase:flag];
  289. }
  290.  
  291. - (int)endCompareLiteral:(const char *)literal length:(unsigned long)len
  292. {
  293.     return [self endCompareLiteral:literal length:len ignoreCase:NO];
  294. }
  295.  
  296. @end
  297.